﻿using System.Collections;
using System.Collections.Generic;

namespace AdvancedTool
{
    /// <summary>
    /// 含事件的字典类
    /// </summary>
    /// <typeparam name="Tkey"></typeparam>
    /// <typeparam name="Tvalue"></typeparam>
    public class AdvancedDictionary<Tkey, Tvalue> : AdvancedDictionaryBase<Tkey, Tvalue>
    {

        public delegate void EventFunction(object self, object key, object value);
        public delegate void SetFunction(object self, object key, object oldValue, object newValue);
        public delegate void ClearFunction(object self);
        public event ClearFunction ClearEvent;
        public event ClearFunction ClearCompleteEvent;
        public event EventFunction GetEvent;
        public event EventFunction InsertEvent;
        public event EventFunction InsertCompleteEvent;
        public event EventFunction RemoveEvent;
        public event EventFunction RemoveCompleteEvent;
        public event SetFunction SetEvent;
        public event SetFunction SetCompleteEvent;
        public event EventFunction ValidateEvent;
        protected override void OnClear()
        {
            if (ClearEvent != null)
            {
                ClearEvent(this);
            }

            base.OnClear();
        }
        protected override void OnClearComplete()
        {
            if (ClearCompleteEvent != null)
            {
                ClearCompleteEvent(this);
            }

            base.OnClearComplete();
        }
        protected override object OnGet(object key, object currentValue)
        {
            if (GetEvent != null)
            {
                GetEvent(this, key, currentValue);
            }

            return base.OnGet(key, currentValue);
        }
        protected override void OnInsert(object key, object value)
        {
            if (InsertEvent != null)
            {
                InsertEvent(this, key, value);
            }
            base.OnInsert(key, value);
        }
        protected override void OnInsertComplete(object key, object value)
        {
            if (InsertCompleteEvent != null)
            {
                InsertCompleteEvent(this, key, value);
            }

            base.OnInsertComplete(key, value);
        }
        protected override void OnRemove(object key, object value)
        {
            if (RemoveEvent != null)
            {
                RemoveEvent(this, key, value);
            }

            base.OnRemove(key, value);
        }
        protected override void OnRemoveComplete(object key, object value)
        {
            if (RemoveCompleteEvent != null)
            {
                RemoveCompleteEvent(this, key, value);
            }

            base.OnRemoveComplete(key, value);
        }
        protected override void OnSet(object key, object oldValue, object newValue)
        {
            if (SetEvent != null)
            {
                SetEvent(this, key, oldValue, newValue);
            }

            base.OnSet(key, oldValue, newValue);
        }
        protected override void OnSetComplete(object key, object oldValue, object newValue)
        {
            if (SetCompleteEvent != null)
            {
                SetCompleteEvent(this, key, oldValue, newValue);
            }
            base.OnSetComplete(key, oldValue, newValue);
        }
        protected override void OnValidate(object key, object value)
        {
            if (ValidateEvent != null)
            {
                ValidateEvent(this, key, value);
            }
            base.OnValidate(key, value);
        }
    }
    /// <summary>
    /// 带事件的字典类基类
    /// </summary>
    /// <typeparam name="Tkey"></typeparam>
    /// <typeparam name="Tvalue"></typeparam>
    public class AdvancedDictionaryBase<Tkey, Tvalue> : DictionaryBase, IDictionary<Tkey, Tvalue>
    {
        public Tvalue this[Tkey key] { get => (Tvalue)Dictionary[key]; set => Dictionary[key] = value; }

        public ICollection<Tkey> Keys
        {
            get
            {
                ICollection<Tkey> tkeys = new List<Tkey>();
                foreach (object item in Dictionary.Keys)
                {
                    tkeys.Add((Tkey)item);
                }
                return tkeys;
            }
        }

        public ICollection<Tvalue> Values
        {
            get
            {
                ICollection<Tvalue> tvalue = new List<Tvalue>();
                foreach (object item in Dictionary.Values)
                {
                    tvalue.Add((Tvalue)item);
                }
                return tvalue;
            }
        }

        public bool IsReadOnly => Dictionary.IsReadOnly;

        public void Add(Tkey key, Tvalue value)
        {
            Dictionary.Add(key, value);
        }

        public void Add(KeyValuePair<Tkey, Tvalue> item)
        {
            Dictionary.Add(item.Key, item.Value);
        }

        public bool Contains(KeyValuePair<Tkey, Tvalue> item)
        {
            return Dictionary.Contains(item.Key);
        }

        public bool ContainsKey(Tkey key)
        {
            return Dictionary.Contains(key);
        }

        public void CopyTo(KeyValuePair<Tkey, Tvalue>[] array, int arrayIndex)
        {
            Dictionary.CopyTo(array, arrayIndex);
        }

        public bool Remove(Tkey key)
        {
            if (ContainsKey(key))
            {
                Dictionary.Remove(key);
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool Remove(KeyValuePair<Tkey, Tvalue> item)
        {
            if (Dictionary.Contains(item))
            {
                Dictionary.Remove(item.Key);
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool TryGetValue(Tkey key, out Tvalue value)
        {
            if (ContainsKey(key))
            {
                value = this[key];
                return true;
            }
            else
            {
                value = default(Tvalue);
                return false;
            }


        }

        IEnumerator<KeyValuePair<Tkey, Tvalue>> IEnumerable<KeyValuePair<Tkey, Tvalue>>.GetEnumerator()
        {
            return (IEnumerator<KeyValuePair<Tkey, Tvalue>>)Dictionary.GetEnumerator();
        }
    }
}
